home *** CD-ROM | disk | FTP | other *** search
/ Enter 2006 February / enter-2006-02.iso / files / Illustrator_CS2_ue_TryOut.exe / bridge / Adobe Bridge 1.0.msi / Data1.cab / _1findReplaceDialog.jsx < prev    next >
Encoding:
Text File  |  2005-03-24  |  23.4 KB  |  630 lines

  1. /**************************************************************************
  2. *
  3. *  @@@BUILDINFO@@@ 61findReplaceDialog.jsx 1.0.0.47 07-Feb-2005
  4. *  Copyright 2005 Adobe Systems Incorporated
  5. *  All Rights Reserved.
  6. *
  7. * NOTICE:  All information contained herein is, and remains the property of
  8. * Adobe Systems Incorporated  and its suppliers,  if any.  The intellectual 
  9. * and technical concepts contained herein are proprietary to  Adobe Systems 
  10. * Incorporated  and its suppliers  and may be  covered by U.S.  and Foreign 
  11. * Patents,patents in process,and are protected by trade secret or copyright 
  12. * law.  Dissemination of this  information or reproduction of this material
  13. * is strictly  forbidden  unless prior written permission is  obtained from 
  14. * Adobe Systems Incorporated.
  15. **************************************************************************/
  16.  
  17. // The Find/Replace floating palette
  18.  
  19. /* NOTES
  20. UIGuide exceptions:
  21. - no 'special character' entry: use REGEXP instead
  22. - Find and Replace EditText boxes should be editable DropDownLists, with max 10 entries,
  23.   but ScriptUI does not provide such a UI element
  24. */
  25.  
  26. // Global properties used:
  27. //    window: LiveObject representing the main window
  28. //    document: LiveObject representing the currently active document (script)
  29.  
  30.  
  31. /////////////////////////////////////////////////////////////////////////
  32. /*    Create a DocFindReplace object and store it as the 'findReplaceObj'
  33.     property of the "edit/findReplace" MenuElement and the "edit/findNext"
  34.     MenuElement.
  35.     
  36.     This property is accessed by the onSelect() callback functions:
  37.     - for the "edit/findReplace" MenuElement, to show the Find/Replace dialog.
  38.     - for the "edit/findNext" MenuElement, to search for the current search string.
  39. */
  40.  
  41. editMenu.findReplace.findReplaceObj = newFindAndReplaceObject (editMenu.findReplace);
  42. editMenu.findNext.findReplaceObj = editMenu.findReplace.findReplaceObj;
  43.  
  44. /*    Define the onSelect() callback function for the "edit/findReplace" MenuElement
  45.     as a function that shows the Find and Replace dialog
  46. */
  47.  
  48. editMenu.findReplace.onSelect = function ()
  49. {
  50.     this.findReplaceObj.show();
  51. }
  52.  
  53. /*    Define the onSelect() callback function for the "edit/findNext" MenuElement
  54.     as a function that searches for the last defined search string.
  55. */
  56.  
  57. editMenu.findNext.onSelect = function ()
  58. {
  59.     this.findReplaceObj.find(false);
  60. }
  61.  
  62. /*    The "edit/findNext" MenuElement is enabled when a current document exists
  63.     and a search string is defined
  64. */
  65.  
  66. editMenu.findNext.onDisplay = function()
  67. {
  68.     this.enabled = (document != null) &&
  69.                    (this.findReplaceObj.currentSearchString().length > 0);
  70. }
  71.  
  72.  
  73. /////////////////////////////////////////////////////////////////////////
  74. // newFindAndReplaceObject: return a new DocFindReplace object
  75. function newFindAndReplaceObject (findReplMenuElement)
  76. {
  77.     var findReplMenuObj = findReplMenuElement;
  78.  
  79.     //    Localizable text strings
  80.     const kStrFind = "$$$/ESToolkit/FindReplaceDlg/Find=&Find";
  81.     const kStrFindNext = "$$$/ESToolkit/FindReplaceDlg/FindNext=&Find Next";
  82.     const kStrSearchFailed = "$$$/ESToolkit/FindReplaceDlg/Alerts/SearchFailed=No matches found";
  83.     const kStrSearchFailedRetry =
  84.         "$$$/ESToolkit/FindReplaceDlg/Alerts/SearchFailedRetry=The end of the document has been reached.^nContinue checking from the beginning?";
  85.     const kStrReplacementDone =
  86.         "$$$/ESToolkit/FindReplaceDlg/Alerts/ReplacementDone=Finished replacing. %1 changes were made.";
  87.  
  88.     /////////////////////////////////////////////////////////////////////////
  89.     // The Find/Replace floating palette resource
  90.     var DFR_dlgResSpec =
  91.     "palette {                                                                    \
  92.         properties: { closeOnKey:CLOSE_ON_KEY },                                \
  93.         text:'$$$/ESToolkit/FindReplaceDlg/title=Find and Replace',                \
  94.         orientation:'row', alignChildren:'top',                                    \
  95.         findPane:    Group {                                                        \
  96.             orientation:'column', alignChildren:'left',                            \
  97.             search:    Group { orientation:'row',                                    \
  98.                 lbl:    StaticText {                                            \
  99.                     text:'$$$/ESToolkit/FindReplaceDlg/FindLbl=Find:',            \
  100.                 },                                                                \
  101.                 string:    EditText {                                                \
  102.                     preferredSize:[200,20],                                        \
  103.                     helpTip:'$$$/ESToolkit/FindReplaceDlg/htFind=A text string to search for'    \
  104.                 }                                                                \
  105.             },                                                                    \
  106.             replace: Group { orientation:'row',                                    \
  107.                 lbl:    StaticText {                                            \
  108.                     text:'$$$/ESToolkit/FindReplaceDlg/ReplaceWith=Replace with:',    \
  109.                 },                                                                \
  110.                 string:    EditText {                                                \
  111.                     preferredSize:[200,20],                                        \
  112.                     helpTip:'$$$/ESToolkit/FindReplaceDlg/htReplaceWith=A text string to replace the search text'    \
  113.                 }                                                                \
  114.             },                                                                    \
  115.             opts:    Group { orientation:'column', alignChildren:'left',            \
  116.                 margins:[0,5,0,0],                                                \
  117.                 matchCase:        Checkbox {                                        \
  118.                     text:'$$$/ESToolkit/FindReplaceDlg/MatchCase=Match &Case',    \
  119.                     helpTip:'$$$/ESToolkit/FindReplaceDlg/htMatchCase=Only matches with the same capitalization will be found'    \
  120.                 },                                                                \
  121.                 wholeWord:        Checkbox {                                        \
  122.                     text:'$$$/ESToolkit/FindReplaceDlg/FindWholeWord=Match &Whole Word',    \
  123.                     helpTip:'$$$/ESToolkit/FindReplaceDlg/htFindWholeWord=Only matches that are an entire word will be found'    \
  124.                 },                                                                \
  125.                 matchRegExp:    Checkbox {                                        \
  126.                     text:'$$$/ESToolkit/FindReplaceDlg/MatchRegExp=Match Regular E&xpression',    \
  127.                     helpTip:'$$$/ESToolkit/FindReplaceDlg/htMatchRegExp=Only strings which match the given regular expression will be found'    \
  128.                 },                                                                \
  129.             }                                                                    \
  130.         },                                                                        \
  131.         btnsPane:    Group {                                                        \
  132.             orientation:'column', alignChildren:'fill',                            \
  133.             find:        Button {                                                \
  134.                 helpTip:'$$$/ESToolkit/FindReplaceDlg/Btn/htFind=Find the specified text string'    \
  135.             },                                                                    \
  136.             replace:    Button {                                                \
  137.                 text:'$$$/ESToolkit/FindReplaceDlg/Btn/Replace=&Replace',        \
  138.                 helpTip:'$$$/ESToolkit/FindReplaceDlg/Btn/htReplace=Replace the selected text with the specified text'    \
  139.             },                                                                    \
  140.             replaceFind: Button {                                                \
  141.                 text:'$$$/ESToolkit/FindReplaceDlg/Btn/ReplaceFind=Replace && Fi&nd',    \
  142.                 helpTip:'$$$/ESToolkit/FindReplaceDlg/Btn/htReplaceFind=Replace the selected text with the specified text, and find the next occurence'    \
  143.             },                                                                    \
  144.             replaceAll:    Button {                                                \
  145.                 text:'$$$/ESToolkit/FindReplaceDlg/Btn/ReplaceAll=Replace &All',\
  146.                 helpTip:'$$$/ESToolkit/FindReplaceDlg/Btn/htReplaceAll=Replace all occurences of the selected text with the specified text'    \
  147.             },                                                                    \
  148.             done:        Button {                                                \
  149.                 text:'$$$/ESToolkit/FindReplaceDlg/Btn/Done=&Done',                \
  150.                 helpTip:'$$$/ESToolkit/FindReplaceDlg/Btn/htDone=Close the Find and Replace dialog'    \
  151.             }                                                                    \
  152.         }                                                                        \
  153.     }";
  154.  
  155.     /////////////////////////////////////////////////////////////////////////
  156.     //    Define a DocFindReplace object
  157.     function DocFindReplace (findReplMenuItem) { this.initSelf(findReplMenuItem); }
  158.  
  159.     /////////////////////////////////////////////////////////////////////////
  160.     //    Define the DocFindReplace 'public method' functions
  161.  
  162.     /*    find(searchWholeDoc)
  163.         Search for the search text.
  164.         * If 'searchWholeDoc' is true, search the entire document,
  165.           otherwise search from the insertion point to the end of the document.
  166.         
  167.         Returns true if the search was successful, false if not.
  168.         
  169.         Called from the Find button event handler, or
  170.         from a keyboard shortcut handler.
  171.     */
  172.     function DFR_find (searchWholeDoc)
  173.     {
  174.         var options = this.getMatchOptions (searchWholeDoc);
  175.         with (this.palette.findPane) {
  176.             var searchString = search.string.text;
  177.             //    Remember that we searched for this text, for preferences
  178.             search.activeSearchString = searchString;
  179.             if (document.find (searchString, options)) {
  180.                 //    Match found: reset search state
  181.                 this.resetFindReplace (false);
  182.                 return true;
  183.             }
  184.             else {
  185.                 /*    Match not found: if already in 'search the whole doc'
  186.                     mode, note the search failure, else, ask if user
  187.                     wants to search from the beginning */
  188.                 if (searchWholeDoc) {
  189.                     //    Already searched whole doc: we're done
  190.                     app.beep();
  191.                     messageBox (this.strSearchFailed);
  192.                     this.resetFindReplace (true);
  193.                     return false;
  194.                 }
  195.                 else if (queryBox (this.strSearchFailedRetry)) {
  196.                     //    Search again, from the top, but don't allow a global search again
  197.                     this.resetFindReplace (false);
  198.                     return this.find (true);
  199.                 }
  200.                 else {
  201.                     this.resetFindReplace (true);
  202.                     return false;
  203.                 }
  204.             }
  205.         }
  206.     } // DFR_find
  207.  
  208.     /*    replace(replaceAll, searchWholeDoc)
  209.         Replace the currently selected text with the contents of
  210.         findPane.replace.string.text.
  211.         * If 'replaceAll' is true, replace all instances of the selected
  212.           text in the document.
  213.         * If 'searchWholeDoc' is true, search the entire document,
  214.           otherwise search from the insertion point to the end of the document.
  215.         Return:
  216.         * true if a match was found
  217.         
  218.         Called from the Replace, Replace & Find, and Replace All button
  219.         event handlers, or from a keyboard shortcut handler.
  220.     */
  221.     function DFR_replace (replaceAll, searchWholeDoc)
  222.     {
  223.         var options = this.getMatchOptions (searchWholeDoc);
  224.         if (replaceAll)
  225.             options += Document.FIND_REPLACEALL;
  226.         with (this.palette.findPane) {
  227.             var searchString = search.string.text;
  228.             var replaceString = replace.string.text;
  229.             //    Remember that we searched for this text, for preferences
  230.             search.activeSearchString = searchString;
  231.             //    Remember that we used this text for replacements, for preferences
  232.             replace.activeReplaceString = replaceString;
  233.             var replacements = document.replace (searchString, replaceString, options);
  234.             if (replacements > 0) {
  235.                 //    Match(es) found: reset search state
  236.                 this.resetFindReplace (false);
  237.                 if (replaceAll)
  238.                     //    Tell user how many replacements were made
  239.                     messageBox (this.strReplacementDone, replacements);
  240.                 return true;
  241.             }
  242.             else {
  243.                 /*    Match not found: if already in 'search the whole doc'
  244.                     mode, note the search failure, else, ask if user
  245.                     wants to search from the beginning */
  246.                 if (searchWholeDoc) {
  247.                     //    Already searched whole doc: we're done
  248.                     messageBox (this.strSearchFailed);
  249.                     this.resetFindReplace (true);
  250.                     return false;
  251.                 }
  252.                 else if (queryBox (this.strSearchFailedRetry)) {
  253.                     //    Search again, from the top, but don't allow a global search again
  254.                     this.resetFindReplace (false);
  255.                     return this.replace (replaceAll, true);
  256.                 }
  257.                 else {
  258.                     this.resetFindReplace (true);
  259.                     return false;
  260.                 }
  261.             }
  262.         }
  263.     } // DFR_replace
  264.  
  265.     /*    show()
  266.         show the Find/Replace palette. If this is the first call to show()
  267.         in this invocation of the IDE, load (or create) the find/replace preferences.
  268.         Called from the Find/Replace menu item onSelect handler
  269.     */
  270.     function DFR_show ()
  271.     {
  272.         if (this.initialShow) {
  273.             /*    First time to show the palette:
  274.                 Look for the prefs object for the DocFindReplace object.
  275.                 If not defined yet, create one with default values.
  276.                 Initialize the UI controls with the preference settings.
  277.             */
  278.             this.initialShow = false;
  279.             if (typeof prefs.findReplacePrefs == "undefined") {
  280.                 //    Create initial prefs object and define default property values
  281.                 prefs.findReplacePrefs = {};
  282.                 for (var i = 0; i < this.prefsProperties.length; i++)
  283.                     prefs.findReplacePrefs[this.prefsProperties[i][0]] = this.prefsProperties[i][1];
  284.             }
  285.             prefs.findReplacePrefs.toSource = DFR_prefsToSource;
  286.             this.initFromPrefs (prefs.findReplacePrefs);
  287.         }
  288.  
  289.         //    On each 'show', reset the find & replace strings and the states of the buttons
  290.         with (this.palette.findPane) {
  291.             /* Replace current 'Find' string if a selection is active in current document.
  292.                For multi-line selections, use only the first line */
  293.             var selection = document.selectedText;
  294.             var nlIndex = selection.indexOf ('\n');
  295.             if (nlIndex >= 0)
  296.                 selection = selection.substring (0, nlIndex);
  297.             if (selection.length == 0)
  298.                 //    Use last known search string
  299.                 search.string.text = search.activeSearchString;
  300.             else
  301.                 //    Use the selection (up to first newline)
  302.                 search.string.text = selection;
  303.             replace.string.text = replace.activeReplaceString;
  304.         }
  305.         this.resetFindReplace (true);
  306.  
  307.         this.palette.show();
  308.         
  309.         //    After the window is visible, give the 'search' edit field the focus
  310.         this.resetFocus (this.palette.findPane.search.string);
  311.     } // DFR_show
  312.     
  313.  
  314.     /////////////////////////////////////////////////////////////////////////
  315.     //    Define the DocFindReplace 'private method' functions
  316.  
  317.     // initSelf(): called from the DocFindReplace ctor
  318.     function DFR_initSelf (findReplMenuElement)
  319.     {
  320.         // Remember our menu item object
  321.         this.menuItem = findReplMenuElement;
  322.  
  323.         // Create the floating palette, link it to the FindReplace object
  324.         var resourceSpec;
  325.         /* define platform-specific hotkeys to close the palette:
  326.            Alt+F4 on Windows and Cmd+W on the Mac */
  327.         if (File.fs == "Windows")
  328.             resourceSpec = this.dlgResSpec.replace ("CLOSE_ON_KEY", '"Alt+F4"');
  329.         else
  330.             resourceSpec = this.dlgResSpec.replace ("CLOSE_ON_KEY", '"Cmd+W"');
  331.         this.palette = new Window (resourceSpec);
  332.         this.palette.findReplaceObj = this; 
  333.  
  334.         // Set update event handlers for Find and Replace strings
  335.         with (this.palette.findPane) {
  336.             search.string.onChanging = function ()
  337.                 {
  338.                     //    Search string is changing: make 'Find' button respond to
  339.                     //    Enter key and reset FindReplace controls state
  340.                     var palette = this.parent.parent.parent;
  341.                     palette.defaultElement = palette.btnsPane.find;
  342.                     palette.findReplaceObj.resetFindReplace (true);
  343.                 }
  344.             replace.string.onChanging = function ()
  345.                 {
  346.                     //    Replace string is changing: make 'Replace' button respond to
  347.                     //    Enter key and reset FindReplace controls state
  348.                     var palette = this.parent.parent.parent;
  349.                     palette.defaultElement = palette.btnsPane.replace;
  350.                     palette.findReplaceObj.resetFindReplace (true);
  351.                 }
  352.         }
  353.  
  354.         // Set update event handlers for 'match options' checkboxes
  355.         with (this.palette.findPane) {
  356.             opts.matchCase.onClick =
  357.             opts.wholeWord.onClick =
  358.             opts.matchRegExp.onClick = function ()
  359.                 {
  360.                     //    A match option is changing: reset FindReplace controls state
  361.                     var palette = this.parent.parent.parent;
  362.                     palette.findReplaceObj.resetFindReplace (true);
  363.                 }
  364.         }
  365.  
  366.         // Set onClick event handlers for the buttons pane
  367.         with (this.palette.btnsPane) {
  368.             find.onClick = function ()
  369.                 {
  370.                     var frObj = this.parent.parent.findReplaceObj;
  371.                     frObj.find (false);
  372.                     /*    We want the search string to retain the focus after a
  373.                         Find/Find Next, so it is easy to change the string.
  374.                         Because Find/Find Next is the default button, it will
  375.                         get Enter keystrokes even if the search string has the
  376.                         focus, unlike in the Replace and Replace & Find cases below. */
  377.                     frObj.resetFocus (frObj.palette.findPane.search.string);
  378.                 };
  379.             replace.onClick = function ()
  380.                 {
  381.                     var frObj = this.parent.parent.findReplaceObj;
  382.                     var replaced = frObj.replace (false, false);
  383.                     /*    After a successful Replace, we want the focus to
  384.                         stay on the Replace button, so the user can easily do
  385.                         another Replace by typing Enter. If the Replace was
  386.                         unsuccessful, return the focus to the search string, so
  387.                         it can be easily changed. */
  388.                     if (replaced)
  389.                         frObj.resetFocus (frObj.palette.btnsPane.replace);
  390.                     else
  391.                         frObj.resetFocus (frObj.palette.findPane.search.string);
  392.                 };
  393.             replaceFind.onClick = function ()
  394.                 {
  395.                     var frObj = this.parent.parent.findReplaceObj;
  396.                     var replacedAndFound = false;
  397.                     if (frObj.replace (false, false))
  398.                         // Only do the 'follow on' find if the replace() matched
  399.                         replacedAndFound = frObj.find (false);
  400.                     /*    After a successful Replace & Find, we want the focus to
  401.                         stay on the 'Replace & Find' button, so the user can easily do
  402.                         another 'Replace & Find' by typing Enter. If the Replace was
  403.                         unsuccessful, return the focus to the search string, so
  404.                         it can be easily changed. */
  405.                     if (replacedAndFound)
  406.                         frObj.resetFocus (frObj.palette.btnsPane.replaceFind);
  407.                     else
  408.                         frObj.resetFocus (frObj.palette.findPane.search.string);
  409.                 };
  410.             replaceAll.onClick = function ()
  411.                 {
  412.                     var frObj = this.parent.parent.findReplaceObj;
  413.                     frObj.replace (true, false);
  414.                     /*    After a 'Replace All', always return the focus to the
  415.                         search string, so it can be easily changed. */
  416.                     frObj.resetFocus (frObj.palette.findPane.search.string);
  417.                 };
  418.             done.onClick = function ()
  419.                 {
  420.                     this.parent.parent.close();
  421.                 };
  422.         }
  423.         
  424.         // Make the 'Done' button respond to the Esc key
  425.         this.palette.cancelElement = this.palette.btnsPane.done;
  426.         
  427.         // Define an onShow event handler that will execute each time the dialog is shown
  428.         this.palette.onShow = function ()
  429.             {
  430.                 // Adjust widths of some text labels for alignment
  431.                 with (this.findPane) {
  432.                     var maxWidth = replace.lbl.size.width;
  433.                     var findWidth = search.lbl.size.width;
  434.                     if (findWidth > maxWidth)
  435.                         maxWidth = findWidth;
  436.                     search.lbl.size.width = maxWidth;
  437.                     replace.lbl.size.width = maxWidth;
  438.                     this.layout.layout(true);
  439.                 }
  440.             };
  441.     } // DFR_initSelf
  442.  
  443.  
  444.     /*    initFromPrefs()
  445.         Initialize values of various controls from the saved 'preference' values.
  446.         Called from first 'show' of the F/R palette.
  447.     */
  448.     function DFR_initFromPrefs (frPrefs)
  449.     {
  450.         with (this.palette) {
  451.             if (frPrefs.paletteLocation != null)
  452.                 frameLocation = frPrefs.paletteLocation;
  453.             else
  454.                 this.palette.center(window);
  455.         }
  456.         with (this.palette.findPane) {
  457.             search.activeSearchString = frPrefs.searchString;
  458.             replace.activeReplaceString = frPrefs.replaceString;
  459.             opts.matchCase.value = frPrefs.matchCase;
  460.             opts.wholeWord.value = frPrefs.wholeWord;
  461.             opts.matchRegExp.value = frPrefs.matchRegExp;
  462.             if (search.activeSearchString.length > 0)
  463.                 //    Initially, if there's a search string, make the
  464.                 //    Find button respond to Enter key
  465.                 this.palette.defaultElement = this.palette.btnsPane.find;
  466.         }        
  467.         this.resetFindReplace (true);
  468.     } // DFR_initFromPrefs
  469.  
  470.  
  471.     /*    updatePrefs()
  472.         Update the find/replace 'preferences' object with current values from the controls.
  473.     */
  474.     function DFR_updatePrefs (frPrefs)
  475.     {
  476.         with (this.palette) {
  477.             frPrefs.paletteLocation = frameLocation;
  478.         }
  479.         with (this.palette.findPane) {
  480.             frPrefs.searchString = search.activeSearchString;
  481.             frPrefs.replaceString = replace.activeReplaceString;
  482.             frPrefs.matchCase = opts.matchCase.value;
  483.             frPrefs.wholeWord = opts.wholeWord.value;
  484.             frPrefs.matchRegExp = opts.matchRegExp.value;
  485.         }        
  486.     } // DFR_updatePrefs
  487.  
  488.  
  489.     /*    resetFindReplace()
  490.         Reset states of the 'find' and 'replace' controls after a state change.
  491.         'newSearch' indicates a new search string: false means searching again
  492.         for same string.
  493.     */
  494.     function DFR_resetFindReplace (newSearch)
  495.     {
  496.         var palette = this.palette;
  497.         var haveSearchString = this.currentSearchString().length > 0;
  498.         var docIsWriteable = true; // replace with "! document.readOnly" if we need to disable F/R for RO docs
  499.         with (palette.btnsPane) {
  500.             find.text = localize (newSearch ? this.strFind : this.strFindNext);
  501.             find.enabled = haveSearchString;
  502.             replace.enabled = (haveSearchString && docIsWriteable);
  503.             replaceFind.enabled = (haveSearchString && docIsWriteable);
  504.             replaceAll.enabled = (haveSearchString && docIsWriteable);
  505.         }
  506.     } // DFR_resetFindReplace
  507.  
  508.  
  509.     /*    resetFocus(control)
  510.         Set keyboard focus to the given 'control', or to the palette if control == null.
  511.     */
  512.     function DFR_resetFocus (control)
  513.     {
  514.         var palette = this.palette;
  515.         palette.active = true;
  516.         if (control)
  517.             control.active = true;
  518.     } // DFR_resetFocus
  519.  
  520.  
  521.     /*    getMatchOptions()
  522.         Return the 'match options' flags to pass to Document.find() or
  523.         Document.replace(), based on the current dialog match options
  524.         checkboxes and the 'searchWholeDoc' parameter.
  525.     */
  526.     function DFR_getMatchOptions (searchWholeDoc)
  527.     {
  528.         var options = 0;
  529.         with (this.palette.findPane) {
  530.             if (searchWholeDoc)
  531.                 options += Document.FIND_WRAPAROUND;
  532.             if (opts.matchCase.value == 0)
  533.                 options += Document.FIND_IGNORECASE;
  534.             if (opts.wholeWord.value != 0)
  535.                 options += Document.FIND_WORDS;
  536.             if (opts.matchRegExp.value != 0)
  537.                 options += Document.FIND_REGEXP;
  538.         }
  539.         return options;
  540.     } // DFR_getMatchOptions
  541.  
  542.     /*    currentSearchString()
  543.         Return the current string to search for: may be empty.
  544.     */
  545.     function DFR_currentSearchString ()
  546.     {
  547.         return this.palette.findPane.search.string.text;
  548.     } // currentSearchString
  549.     
  550.     /*    DFR_prefsToSource()
  551.         Return a string that is executable code which creates the findReplacePrefs object.
  552.         DFR_prefsToSource is assigned as the toSource() function for the findReplacePrefs object.
  553.     */
  554.     function DFR_prefsToSource()
  555.     {
  556.         //    Get the DocFindReplace object: it has the names of preference properties
  557.         var frObj = editMenu.findReplace.findReplaceObj;
  558.         
  559.         //    Update the find/replace preference object with current preferences values.
  560.         frObj.updatePrefs (prefs.findReplacePrefs);
  561.  
  562.         /*    Iterate thru the find/replace preference properties, appending each
  563.             property name / value pair to the source string we are building */
  564.         var src = "{ ";
  565.         for (var i = 0; i < frObj.prefsProperties.length; i++) {
  566.             if (i > 0)
  567.                 src += ", ";
  568.             src += strVal (prefs.findReplacePrefs, frObj.prefsProperties[i][0]);
  569.         }
  570.         src += " }";
  571.         return src;
  572.         
  573.         //    Utility that returns a string for the named 'prop' / value pair
  574.         function strVal (prefs, prop)
  575.         {
  576.             var str = prop + ": ";
  577.             var value = prefs[prop];
  578.             if (typeof value == 'object')
  579.                 str += value.toSource();
  580.             else if (typeof value == "string")
  581.                 str += "'" + value.toString() + "'";
  582.             else
  583.                 str += value.toString();
  584.             return str;
  585.         }
  586.     } // DFR_prefsToSource
  587.     
  588.  
  589.     /////////////////////////////////////////////////////////////////////////
  590.     // Attach 'public methods' to Object's prototype
  591.     DocFindReplace.prototype.find = DFR_find;
  592.     DocFindReplace.prototype.replace = DFR_replace;
  593.     DocFindReplace.prototype.show = DFR_show;
  594.     
  595.     // Attach 'private methods' to Object's prototype
  596.     DocFindReplace.prototype.initSelf = DFR_initSelf;
  597.     DocFindReplace.prototype.initFromPrefs = DFR_initFromPrefs;
  598.     DocFindReplace.prototype.updatePrefs = DFR_updatePrefs;
  599.     DocFindReplace.prototype.resetFindReplace = DFR_resetFindReplace;
  600.     DocFindReplace.prototype.resetFocus = DFR_resetFocus;
  601.     DocFindReplace.prototype.getMatchOptions = DFR_getMatchOptions;
  602.     DocFindReplace.prototype.currentSearchString = DFR_currentSearchString;
  603.     
  604.     // Attach 'member variables' to Object's prototype
  605.     DocFindReplace.prototype.strFind = kStrFind;
  606.     DocFindReplace.prototype.strFindNext = kStrFindNext;
  607.     DocFindReplace.prototype.strSearchFailed = kStrSearchFailed;
  608.     DocFindReplace.prototype.strSearchFailedRetry = kStrSearchFailedRetry;
  609.     DocFindReplace.prototype.strReplacementDone = kStrReplacementDone;
  610.     DocFindReplace.prototype.dlgResSpec = DFR_dlgResSpec;
  611.  
  612.     /////////////////////////////////////////////////////////////////////////
  613.     // Create an instance, set some initial values, and return it
  614.     var frObj = new DocFindReplace(findReplMenuElement);
  615.     frObj.initialShow = true;
  616.     frObj.prefsProperties = [
  617.         ["paletteLocation", null],
  618.         ["matchCase", false],
  619.         ["wholeWord", false],
  620.         ["matchRegExp", false],
  621.         ["searchString", ""],
  622.         ["replaceString", ""]
  623.     ];
  624.  
  625.     return frObj;
  626.  
  627. } // newFindAndReplaceObject
  628.  
  629.  
  630.